From: Colin Walters Date: Sun, 5 Dec 2010 21:46:48 +0000 (-0500) Subject: StTextureCache: Plug leaks in tiled image loading X-Git-Tag: archive/raspbian/50.5-1+rpi1~1^2~1013^2^2~9378 X-Git-Url: https://dgit.raspbian.org/%22http://www.example.com/cgi/%22/%22http:/www.example.com/cgi/%22?a=commitdiff_plain;h=bdfc516715201ab934e2a166acf9a1265aafa4be;p=gnome-shell.git StTextureCache: Plug leaks in tiled image loading We weren't freeing the whole pixbuf, nor were we the GList of subpixbufs. Plug both of these leaks in the error handling path and in the default case. All of the unreffing/cleanup should happen in the GDestroyNotify for the result, not some in the handler. https://bugzilla.gnome.org/show_bug.cgi?id=636489 --- diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c index 35931da36..520b7d750 100644 --- a/src/st/st-texture-cache.c +++ b/src/st/st-texture-cache.c @@ -1183,9 +1183,7 @@ on_sliced_image_loaded (GObject *source_object, { ClutterActor *actor = load_from_pixbuf (GDK_PIXBUF (list->data)); clutter_actor_hide (actor); - clutter_container_add_actor (CLUTTER_CONTAINER (data->group), actor); - g_object_unref (list->data); } } @@ -1198,6 +1196,17 @@ on_data_destroy (gpointer data) g_free (d); } +static void +free_glist_unref_gobjects (gpointer p) +{ + GList *list = p; + GList *iter; + + for (iter = list; iter; iter = iter->next) + g_object_unref (iter->data); + g_list_free (list); +} + static void load_sliced_image (GSimpleAsyncResult *result, GObject *object, @@ -1223,17 +1232,14 @@ load_sliced_image (GSimpleAsyncResult *result, for (x = 0; x < width; x += data->grid_height) { GdkPixbuf *pixbuf = gdk_pixbuf_new_subpixbuf (pix, x, y, data->grid_width, data->grid_height); - if (!pixbuf) - { - g_simple_async_result_set_error (result, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, - "Has failed thumbnail"); - break; - } + g_assert (pixbuf != NULL); res = g_list_append (res, pixbuf); } } - if (res) - g_simple_async_result_set_op_res_gpointer (result, res, (GDestroyNotify)g_list_free); + /* We don't need the original pixbuf anymore, though the subpixbufs + will hold a reference. */ + g_object_unref (pix); + g_simple_async_result_set_op_res_gpointer (result, res, free_glist_unref_gobjects); } /**